<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>MCP SSE Client</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
      line-height: 1.6;
      margin: 0;
      padding: 20px;
      color: #333;
      max-width: 1200px;
      margin: 0 auto;
    }

    h1, h2, h3 {
      color: #0066cc;
    }

    #messages {
      height: 300px;
      overflow-y: auto;
      border: 1px solid #ddd;
      padding: 10px;
      margin-bottom: 20px;
      background-color: #f9f9f9;
      border-radius: 4px;
      font-family: monospace;
    }

    #message-form {
      margin-bottom: 20px;
    }

    textarea {
      width: 100%;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 4px;
      min-height: 100px;
      font-family: monospace;
      margin-bottom: 10px;
    }

    button {
      background-color: #0066cc;
      color: white;
      border: none;
      padding: 10px 20px;
      border-radius: 4px;
      cursor: pointer;
      font-size: 16px;
    }

    button:hover {
      background-color: #0055aa;
    }

    .message {
      margin-bottom: 8px;
      border-bottom: 1px solid #eee;
      padding-bottom: 8px;
    }

    .message-time {
      color: #666;
      font-size: 12px;
    }

    .message-direction {
      display: inline-block;
      padding: 2px 6px;
      border-radius: 3px;
      font-size: 12px;
      margin-right: 8px;
    }

    .direction-incoming {
      background-color: #e7f3ff;
      color: #0066cc;
    }

    .direction-outgoing {
      background-color: #e7ffe7;
      color: #007700;
    }

    .message-content {
      white-space: pre-wrap;
      background-color: #fff;
      padding: 8px;
      border-radius: 4px;
      overflow-x: auto;
    }

    .connection-info {
      margin-bottom: 20px;
      padding: 10px;
      background-color: #f0f0f0;
      border-radius: 4px;
    }

    .status {
      display: inline-block;
      width: 12px;
      height: 12px;
      border-radius: 50%;
      margin-right: 8px;
    }

    .status-connected {
      background-color: #00cc00;
    }

    .status-disconnected {
      background-color: #cc0000;
    }
  </style>
</head>
<body>
  <h1>MCP SSE Client</h1>

  <div class="connection-info">
    <div id="connection-status">
      <span class="status status-disconnected"></span> Disconnected
    </div>
    <div>
      <label for="server-url">Server URL:</label>
      <input type="text" id="server-url" value="http://localhost:3001" style="width: 250px;">
      <button id="connect-btn">Connect</button>
      <button id="disconnect-btn" disabled>Disconnect</button>
    </div>
  </div>

  <h2>Send Message</h2>
  <div id="message-form">
    <textarea id="message-input" placeholder="Enter your JSON message here...">
{
  "jsonrpc": "2.0",
  "method": "mcp__get_server_info",
  "id": "1",
  "params": {}
}
</textarea>
    <button id="send-btn" disabled>Send Message</button>
  </div>

  <h2>Messages</h2>
  <div id="messages"></div>

  <script>
    let eventSource = null;
    const messagesContainer = document.getElementById('messages');
    const messageInput = document.getElementById('message-input');
    const sendBtn = document.getElementById('send-btn');
    const connectBtn = document.getElementById('connect-btn');
    const disconnectBtn = document.getElementById('disconnect-btn');
    const serverUrlInput = document.getElementById('server-url');
    const connectionStatus = document.getElementById('connection-status');

    // Function to connect to the SSE server
    function connect() {
      const serverUrl = serverUrlInput.value.trim();
      if (!serverUrl) {
        alert('Please enter a valid server URL');
        return;
      }

      try {
        // Generate a unique client ID
        const clientId = 'client_' + Date.now();

        // Create a new EventSource
        eventSource = new EventSource(`${serverUrl}/events?clientId=${clientId}`);

        // Listen for messages
        eventSource.onmessage = (event) => {
          const data = event.data;
          addMessage('incoming', data);
        };

        // Handle connection open
        eventSource.onopen = () => {
          connectionStatus.innerHTML = '<span class="status status-connected"></span> Connected';
          connectBtn.disabled = true;
          disconnectBtn.disabled = false;
          sendBtn.disabled = false;
          addMessage('system', 'Connected to server');
        };

        // Handle errors
        eventSource.onerror = (error) => {
          console.error('EventSource error:', error);
          addMessage('system', 'Connection error. Reconnecting...');
          connectionStatus.innerHTML = '<span class="status status-disconnected"></span> Error connecting';
        };
      } catch (error) {
        console.error('Error connecting to server:', error);
        addMessage('system', `Error connecting: ${error.message}`);
      }
    }

    // Function to disconnect from the SSE server
    function disconnect() {
      if (eventSource) {
        eventSource.close();
        eventSource = null;

        connectionStatus.innerHTML = '<span class="status status-disconnected"></span> Disconnected';
        connectBtn.disabled = false;
        disconnectBtn.disabled = true;
        sendBtn.disabled = true;

        addMessage('system', 'Disconnected from server');
      }
    }

    // Function to send a message to the server
    async function sendMessage() {
      const message = messageInput.value.trim();
      if (!message) {
        alert('Please enter a message to send');
        return;
      }

      try {
        // Parse message to validate JSON
        const jsonMessage = JSON.parse(message);

        // Send the message to the server
        const serverUrl = serverUrlInput.value.trim();
        const response = await fetch(`${serverUrl}/send`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: message,
        });

        const responseData = await response.json();

        if (response.ok) {
          addMessage('outgoing', message);
        } else {
          addMessage('system', `Error sending message: ${responseData.message || 'Unknown error'}`);
        }
      } catch (error) {
        console.error('Error sending message:', error);
        addMessage('system', `Error sending message: ${error.message}`);
      }
    }

    // Function to add a message to the messages container
    function addMessage(direction, content) {
      const messageDiv = document.createElement('div');
      messageDiv.className = 'message';

      const now = new Date();
      const time = now.toLocaleTimeString();

      let directionLabel = '';
      let directionClass = '';

      switch (direction) {
        case 'incoming':
          directionLabel = 'Received';
          directionClass = 'direction-incoming';
          break;
        case 'outgoing':
          directionLabel = 'Sent';
          directionClass = 'direction-outgoing';
          break;
        case 'system':
          directionLabel = 'System';
          directionClass = '';
          break;
      }

      let contentDisplay = content;

      // Try to pretty-print JSON if it's not a system message
      if (direction !== 'system') {
        try {
          contentDisplay = JSON.stringify(JSON.parse(content), null, 2);
        } catch (e) {
          // Not valid JSON, just use as-is
        }
      }

      messageDiv.innerHTML = `
        <div>
          <span class="message-time">${time}</span>
          <span class="message-direction ${directionClass}">${directionLabel}</span>
        </div>
        <div class="message-content">${direction === 'system' ? content : contentDisplay}</div>
      `;

      messagesContainer.appendChild(messageDiv);

      // Auto-scroll to bottom
      messagesContainer.scrollTop = messagesContainer.scrollHeight;
    }

    // Set up event listeners
    connectBtn.addEventListener('click', connect);
    disconnectBtn.addEventListener('click', disconnect);
    sendBtn.addEventListener('click', sendMessage);

    // Allow pressing Enter in the input to send a message
    messageInput.addEventListener('keydown', (event) => {
      if (event.key === 'Enter' && event.ctrlKey) {
        sendMessage();
        event.preventDefault();
      }
    });

    // Add a welcome message
    addMessage('system', 'Welcome to the MCP SSE Client. Click Connect to start.');
  </script>
</body>
</html>
